package com.dengqi.mymodule.activity.camera;

import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.dengqi.mymodule.BaseActivity;
import com.dengqi.mymodule.R;
import com.dengqi.mymodule.tools.BitmapUtils;
import com.dengqi.mymodule.tools.UriUtils;

import java.io.File;

/**
 * 开启相机方式：
 * 第一种：使用相机API（即Camera类）来自定义拍照
 * 第二种是使用Intent调用系统相机来拍照
 * 相机参考：https://blog.csdn.net/huangxiaoguo1/article/details/53518952
 * 相册参考：https://www.cnblogs.com/epmouse/p/5421048.html
 * https://blog.csdn.net/m0_37930105/article/details/76577775
 * https://blog.csdn.net/u012483116/article/details/51994847
 * 裁剪参考：https://www.jianshu.com/p/b785a4057388
 * 开源库：
 * https://github.com/crazycodeboy/TakePhoto
 * https://github.com/donglua/PhotoPicker
 *
 * Created by dell on 2018/6/27
 */

public class CameraActivity extends BaseActivity {

    ImageView imageView;
    static final int REQUEST_CODE_CAMERA = 1;
    static final int REQUEST_CODE_ALBUM = 2;
    static final int REQUEST_CODE_CROP = 3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cameralibrary);

        imageView = findViewById(R.id.imageView);

    }

    public void onBtn1(View view) {
        startCamare();
    }

    public void onBtn2(View view) {
        File file = new File(Environment.getExternalStorageDirectory(),"yummy.png");
//        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "pic1.jpg");
        if(file.exists()){
            Uri sourceUri = UriUtils.file2Uri(this, file);
            startCrop(sourceUri);
        }else{
            Toast.makeText(this, "文件不存在",Toast.LENGTH_SHORT).show();
        }
    }

    public void onBtn31(View view) {
        startAlbum(1);
    }
    public void onBtn32(View view) {
        startAlbum(2);
    }
    public void onBtn33(View view) {
        startAlbum(3);
    }

    public void onBtn4(View view) {
        startActivity(new Intent(this, CameraOutputActivity.class));
    }

    public void onBtn5(View view) {
        startActivity(new Intent(this, CameraUtilsActivity.class));
    }

    public void onBtn6(View view) {
        startActivity(new Intent(this, CameraLibraryActivity.class));
    }

    /**
     * 启动系统相机（拍照结果不保留在相册中）
     * 坑一：
     * 默认情况下，即不需要指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
     * 照相机有自己默认的存储路径，拍摄的照片将返回一个缩略图。
     * 如果想访问原始图片，可以通过dat extra能够得到原始图片位置。
     * 总结：如果指定了目标uri，data就没有数据，如果没有指定uri，则data就返回有数据！
     * 坑二：
     * Android7.0中file:// URI 会触发 FileUriExposedException需要添加FileProvider
     * 坑三：
     * Android6.0需要申请照相机权限
     *
     */
    private void startCamare() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
        }
        //将拍照结果保存至Uri中
        //7.0需要写入权限
//        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.parse("file://" + mFilePath));
        startActivityForResult(intent, REQUEST_CODE_CAMERA);
    }

    /**
     * 启动裁剪
     * 坑一：
     * return-data设置true返回缩略图、return-data设置false需要指定uri，返回指定裁剪大小
     * 总结：如果设置false，data就没有数据，如果设置true，则data就返回有数据！
     * 坑二：
     * return-data设置true：小米手机不跳系统裁剪
     * 坑三：
     * file转uri：android7.0开始需要使用fileprodiver来转换
     * 坑四：
     * 7.0uri需要读写权限
     * 读：file2Uri
     * 写：拍照，裁剪这种需要把数据写入到uri
     */
    private void startCrop(Uri sourceUri) {

        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intent.setDataAndType(sourceUri, "image/*");
//        intent.putExtra("crop", true);
        // 设置x,y的比例，截图方框就按照这个比例来截 若设置为0,0，或者不设置 则自由比例截图
//        intent.putExtra("aspectX", 1);
//        intent.putExtra("aspectY", 1);
        // 裁剪区的宽和高 其实就是裁剪后的显示区域 若裁剪的比例不是显示的比例，则自动压缩图片填满显示区域。若设置为0,0 就不显示。若不设置，则按原始大小显示
//        intent.putExtra("outputX", 150);
//        intent.putExtra("outputY", 150);
        /** ---指定uri获取原图，需要注意图片太大溢出/没有指定uri获得缩略图--- */
        /** return-data设置true：小米手机不跳系统裁剪 */
        intent.putExtra("return-data", true);
        //如果指定了目标uri，data就没有数据，如果没有指定uri，则data就返回有数据！
//        intent.putExtra("return-data", false);
//        Uri targetUri = UriUtils.file2Uri(this, new File(Environment.getExternalStorageDirectory(), "activity_singleItem.jpg"));
//        UriUtils.applyUri(this, intent, targetUri);
//        intent.putExtra(MediaStore.EXTRA_OUTPUT, targetUri);
//        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        startActivityForResult(intent, REQUEST_CODE_CROP);
    }

    /**
     * 启动相册
     * 坑一：
     * 请求系统相册有三个Action（注意以下  图库（缩略图）   和  图片（原图）  的区别）
     * ACTION_OPEN_DOCUMENT    仅限4.4或以上使用  默认打开原图
     * ACTION_GET_CONTENT      4.4以下默认打开缩略图  。 以上打开文件管理器 供选择，选择图库打开为缩略图页面，选择图片打开为原图浏览
     * ACTION_PICK             都可用，打开默认是缩略图界面，还需要进一步点开查看
     * 注：uri只跟 图库还是图片选择有关，跟action无关，是选择图片还是图库才跟action有关
     *
     * ACTION_OPEN_DOCUMENT  直接打开的是图片文件
     * ACTION_GET_CONTENT       打开后可选择是图库获取还是图片获取 file类型的Uri或content类型的URI
     * ACTION_PICK  直接打开的就是图库 content类型的URI
     * 坑二：
     * 相册在6.0后需要申请访问存储设备权限
     * 坑三：
     * Android系统从4.4版本开始，选取相册中图片不再返回图片真实的Uri了，而是一个封装过的Uri，隐因此4.4版本以上要对这个Uri进行解析。
     */
    private void startAlbum(int type){
        Intent intent;
        switch (type){
            case 1:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("image/*") ;
                    startActivityForResult(intent , REQUEST_CODE_ALBUM) ;
                }
                break;
            case 2:
                intent = new Intent(Intent.ACTION_GET_CONTENT) ; //"android.intent.action.GET_CONTENT"
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType( "image/*"); //查看类型 String IMAGE_UNSPECIFIED = "image/*";
                startActivityForResult(intent, REQUEST_CODE_ALBUM) ;
                break;
            case 3:
                intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); //调用android的图库
                intent.setType( "image/*");
                startActivityForResult(intent, REQUEST_CODE_ALBUM);
                break;
        }

    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_CAMERA && resultCode == RESULT_OK) {
            if (data != null && data.hasExtra("data")) {
                //可能尚未指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); 返回缩略图
                Bitmap bitmap = data.getExtras().getParcelable("data");
                imageView.setImageBitmap(bitmap);
                //裁剪
//                Uri uri = UriUtils.bitmap2Uri(this, bitmap);
//                startCrop(uri);
            } else {
                //由于指定了目标uri，存储在目标uri，intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
                //...
                //删除拍照的照片
//                file.delete();
            }
        } else if (requestCode == REQUEST_CODE_CROP && resultCode == RESULT_OK) {
            if (data != null && data.hasExtra("data")) {
                //可能尚未指定intent.putExtra("return-data", true); 返回缩略图
                Bitmap bitmap = data.getExtras().getParcelable("data");
                imageView.setImageBitmap(bitmap);
            } else {
                //由于指定了目标uri，存储在目标uri，intent.putExtra("return-data", false);
//                File file = new File(Environment.getExternalStorageDirectory(), "activity_singleItem.jpg");
//                if(file.exists()){
//                    imageView.setImageBitmap(BitmapUtils.file2Bitmap(file, 1024, 1024));
//                    删除拍照的照片
//                    file.delete();
//                }
            }
        } else if (requestCode == REQUEST_CODE_ALBUM && resultCode == RESULT_OK) {
            String imagePath = "";
            Uri uri = data.getData();
            if (uri == null) {
                return;
            }
            boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
            if (isKitKat && DocumentsContract.isDocumentUri(this, uri)) {
                // ExternalStorageProvider
                if (isExternalStorageDocument(uri)) {
                    String docId = DocumentsContract.getDocumentId(uri);
                    String[] split = docId.split(":");
                    String type = split[0];
                    if ("primary".equalsIgnoreCase(type)) {
                        imagePath = Environment.getExternalStorageDirectory() + "/" + split[1];
                    }
                }
                // DownloadsProvider
                else if (isDownloadsDocument(uri)) {
                    String docId = DocumentsContract.getDocumentId(uri);
                    Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                    imagePath = getImagePath(contentUri, null, null);
                }
                // MediaProvider
                else if (isMediaDocument(uri)) {
                    String docId = DocumentsContract.getDocumentId(uri);
                    String[] split = docId.split(":");
                    String type = split[0];
                    Uri contentUri = null;
                    if ("image".equals(type)) {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[]{split[1]};
                    imagePath = getImagePath(contentUri, selection, selectionArgs);
                }
            } else if ("content".equalsIgnoreCase(uri.getScheme())) {
                //如果是content类型的URI，则使用普通方式处理 （图库选取）
                imagePath = getImagePath(uri, null, null);
            } else if ("file".equalsIgnoreCase(uri.getScheme())) {
                //如果是file类型的Uri,直接获取图片路径即可（文件选取）
                imagePath = uri.getPath();
            }

            File file = new File(imagePath);
            if (file.exists()) {
                imageView.setImageBitmap(BitmapUtils.file2Bitmap(file, 1024, 1024));
            }
        }
    }

    private String getImagePath(Uri uri, String selection, String[] selectionArgs) {
        String path = null;
        //通过Uri和selection来获取真实的图片路径
        Cursor cursor = getContentResolver().query(uri, null, selection, selectionArgs, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

}
